Skip to content

refactor: qhull-only Delaunay callback, exact JAX visibility-walk point location - #368

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/delaunay-qhull-callback
Jul 9, 2026
Merged

Jammy2211 merged 1 commit into
mainfrom
feature/delaunay-qhull-callback

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

Shrinks the JAX-path Delaunay pure_callback to qhull-only and moves point location, dual areas and split points inside the JIT program. The old callback did 40-320 ms of host-serial work per likelihood evaluation (scaling with over-sampling), serialized per vmap lane (vmap_method="sequential") — the measured reason the A100 Delaunay cell runs at 106.8 ms/lane vs rectangular's 32.9 ms (autolens_profiling results/notes/sparse_vs_dense_inversion_path.md). Expected effect: Delaunay vmap lane → ~40-50 ms (rectangular parity); to be re-profiled on the A100 when RAL returns.

Point location is the same visibility-walk algorithm find_simplex itself uses, via qhull's tri.neighbors, as a masked fixed-trip lax.fori_loop chunked over query points — exact by construction. The planned 2-ring locator was implemented first and rejected by the parity gate (Δlog-evidence −0.77 on the production config; only ~31% of the relocated source-plane grid is inside the mesh hull and caustic geometry defeats ring-coverage arguments) — see the issue thread for the investigation.

Known trade-off: single-thread CPU JAX-path per-eval is ~20% slower than the old callback (CPU-JAX runs the walk slower than scipy's C). GPU/vmap is the target of this refactor; the eager numpy path is byte-identical.

API Changes

None — internal changes only. jax_delaunay / jax_delaunay_matern signatures and return contracts (shapes, dtypes, -1 padding conventions) are unchanged; the numpy/scipy path (scipy_delaunay, scipy_delaunay_matern) is byte-identical.
See full details below.

Test Plan

  • Full suite in the task worktree: 873 passed
  • New numpy-only unit tests (test_delaunay_walk.py): walk locator vs scipy.find_simplex on uniform + adaptive (blob/ring) meshes; outside-hull rows equal the KDTree nearest-vertex assignment exactly; fp edge ties must still contain the query; vertex/edge-midpoint degeneracies; adjacency tables vs the triangulation
  • Production-scale parity gate (HST, 1500-vertex Hilbert/Delaunay, MGE-60 lens, ConstantSplit): full-pipeline JIT − eager = 5.4e-9 (old JAX path: 5.2e-9); pinned log-evidence 29110.92085793 holds; mapping identity vs find_simplex on the real border-relocated grids: 100.0000%
  • Phase 2 (follow-up PR, library-first gate): permanent parity suite in autolens_workspace_test incl. a near-caustic configuration
  • A100 re-profile (autolens_profiling runtime sweep) when RAL is back

Validation checklist (--auto run)

  • Effective level: supervised (header: supervised, cap: refactor → safe); ship sign-off + Heart YELLOW reason-set acknowledged by the human in-session 2026-07-09
  • Plan: on the issue (refactor: qhull-only Delaunay callback, JAX point location #367), locator design amended mid-run (2-ring → visibility walk) with the parity evidence documented on the issue before ship
  • Gate: tests 873 passed · smoke pending (targeted delaunay smoke recommended post-merge; cluster scripts are no_run-parked) · review-faculty verdict posted to the issue after PR-open · Heart YELLOW within launch ack
  • Human: plan sound in hindsight?
  • Human: diff matches plan (no scope creep)?
  • Human: merge, amend, or reject — then log the outcome
Full API Changes (for automation & release notes)

Removed

  • None from the public surface. (Internal-only: the interim helpers of this branch's first iteration never shipped.)

Added (module-internal helpers, not exported via autoarray.__init__)

  • inversion.mesh.interpolator.delaunay.scipy_delaunay_tri_only(points_np) — qhull-only host callback returning simplices_padded, simplex_neighbors, vertex_simplex
  • inversion.mesh.interpolator.delaunay.pix_indexes_delaunay_walk_from(query_points, points, simplices_padded, simplex_neighbors, vertex_simplex, xp) — exact visibility-walk point locator (NumPy/JAX)
  • Module constants DELAUNAY_LOCATE_CHUNK, DELAUNAY_WALK_STEPS

Changed Behaviour

  • jax_delaunay / jax_delaunay_matern: identical return contract; the mappings are now computed in-JIT via the visibility walk instead of on the host. Measured identical to find_simplex on production grids (100.0000%); the only theoretical divergence is fp ties on shared edges, which are interpolation-identical.

Migration

  • None required.

🤖 Generated with Claude Code

… point location

The JAX-path pure_callback previously ran the full scipy_delaunay
pipeline on the host every likelihood evaluation (qhull triangulation +
find_simplex on the data and split grids + numpy assembly) - 40-320 ms
of host-serial work that scales with over-sampling and serializes per
vmap lane. The callback now returns only the qhull triangulation and
its adjacency arrays (tri.neighbors plus one incident simplex per
vertex); point location, dual areas and split points run inside the
JIT program, on GPU and batched across vmap lanes in production.

Point location uses the same visibility-walk algorithm find_simplex
itself uses (nearest-vertex start, step through the neighbor opposite
the most negative barycentric weight, hull exit -> nearest-vertex
fallback), as a masked fixed-trip lax.fori_loop chunked over query
points. Mappings are exact: 100.000% identity vs find_simplex on
production HST grids; full-pipeline JIT log-evidence matches eager to
5.4e-9 (previous JAX path: 5.2e-9), pinned value 29110.92085793 holds.

The numpy/scipy path is byte-identical and the jax_delaunay /
jax_delaunay_matern return contracts (shapes, dtypes, -1 padding) are
unchanged, so no downstream edits are required.

PyAutoArray#367 (phase 1 of 2; phase 2 adds the autolens_workspace_test
parity suite).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Jammy2211

Copy link
Copy Markdown
Collaborator Author

Phase 2 parity-guard PR (merge after this one): PyAutoLabs/autolens_workspace_test#155

@Jammy2211
Jammy2211 merged commit 89a5fbd into main Jul 9, 2026
4 checks passed
@Jammy2211
Jammy2211 deleted the feature/delaunay-qhull-callback branch July 9, 2026 14:21
@Jammy2211 Jammy2211 removed the pending-release PR queued for the next release build label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant